package com.my.main.common.utils;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


/**
 * 敏感字及非法字符过滤，身份证号码
 * 
 * @author 修恒
 * @Date 2014年12月23日
 */
public class ValidataUtil {

	public static Boolean FLAG = false; // 判断标志
	public static List<String> WORDLIST; // 敏感词
	public static List<String> WORDARRAYLIST; // 敏感词组
	public static String[] WORDS = { "*", "#", "\"", "\'" };
	public static String[] WORDSARRAY = { "alert", "input", "put", "get", "set", "this", "that", "<>", "<!", "<! --", "<!--", "< #", "<#", "\b", "\f", "//", "/*", "</", "<script>", "<script" };

	/**
	 * 
	 * @param str
	 *            待验证的字符串
	 * @return true：有非法字符 false：无非法字符
	 */
	public static Boolean validataWord(String str) {
		if (validateNull(str)) {
			return false;
		}
		if (null == WORDLIST || WORDLIST.size() == 0) {
			WORDLIST = getWord();
		}
		if (null == WORDARRAYLIST || WORDARRAYLIST.size() == 0) {
			WORDARRAYLIST = getWordArray();
		}
		// 待检查参数
		String[] param = getWordFromParam(str);
		for (int i = 0; i < param.length; i++) {
			if (WORDLIST.contains(param[i])) {
				FLAG = true;
				break;
			} else {
				FLAG = false;
			}
		}
		if (!FLAG) {
			for (String str1 : WORDARRAYLIST) {
				if (str.contains(str1)) {
					FLAG = true;
					break;
				} else {
					FLAG = false;
				}
			}
		}
		return FLAG;
	}

	/**
	 * 判断是否为空
	 * 
	 * @param str
	 * @return true:为空，false不为空
	 */
	public static Boolean validateNull(String str) {
		if (null == str || "".equals(str)) {
			return true;
		} else {
			return false;
		}
	}

	// /**
	// * 验证数值型
	// *
	// * @param obj
	// * @return true是数值型，false非数值型
	// */
	//
	// public static Boolean validataNumber(Object obj) {
	// try {
	// Integer.valueOf(obj.toString());
	// } catch (Exception e) {
	// return false;
	// }
	// return true;
	// }

	/**
	 * 验证数值型
	 * 
	 * @param obj
	 *            待验证对象
	 * @param flag
	 *            是否有小数点，0：整数，1：小数
	 * @return true是数值型，false非数值型
	 */

	public static Boolean validataNumber(Object obj, Integer flag) {
		Pattern pattern = null;
		if (flag == 1) {
			pattern = Pattern.compile("^[0-9]+(.[0-9]*)?$");
		} else {
			pattern = Pattern.compile("^[0-9]+$");
		}
		try {
			return pattern.matcher(obj.toString()).matches();
		} catch (Exception e) {
			return false;
		}
	}

	/**
	 * 验证数值型
	 * 
	 * @param obj
	 *            待验证对象
	 * @return true是数值型，false非数值型
	 */
	public static Boolean validataNumber(Object obj) {
		return validataNumber(obj, 1);
	}

	// 加载过滤列表
	private static List<String> getWord() {
		// 从文件或数据库中读取过滤列表
		List<String> wordList = readFromFile();
		if (null == wordList || wordList.size() == 0) {
			wordList = Arrays.asList(WORDS);
		}
		return wordList;
	}

	// 加载过滤列表
	private static List<String> getWordArray() {
		// 从文件或数据库中读取过滤列表
		List<String> wordList = readFromFile();
		if (null == wordList || wordList.size() == 0) {
			wordList = Arrays.asList(WORDSARRAY);
		}
		return wordList;
	}

	private static String[] getWordFromParam(String str) {
		char[] param = str.toCharArray();
		String[] value = new String[param.length];
		for (int i = 0; i < param.length; i++) {
			value[i] = String.valueOf(param[i]);
		}
		return value;
	}

	private static List<String> readFromFile() {
		// List<String> wordList = new ArrayList<String>();
		// 从文件或数据库中读取过滤列表
		return null;
	}

	/**
	 * 功能：身份证的有效验证
	 * 
	 * @param IDStr
	 *            身份证号
	 * @return 有效：返回null 无效：返回String信息
	 * @throws ParseException
	 */
	public static String IDCardValidate(String IDStr) {
		String errorInfo = "";// 记录错误信息
		String[] ValCodeArr = { "1", "0", "x", "9", "8", "7", "6", "5", "4", "3", "2" };
		String[] Wi = { "7", "9", "10", "5", "8", "4", "2", "1", "6", "3", "7", "9", "10", "5", "8", "4", "2" };
		String Ai = "";
		// ================ 号码的长度 15位或18位 ================
		if (IDStr.length() != 15 && IDStr.length() != 18) {
			errorInfo = "身份证号码长度应该为15位或18位。";
			return errorInfo;
		}
		// =======================(end)========================

		// ================ 数字 除最后以为都为数字 ================
		if (IDStr.length() == 18) {
			Ai = IDStr.substring(0, 17);
		} else if (IDStr.length() == 15) {
			Ai = IDStr.substring(0, 6) + "19" + IDStr.substring(6, 15);
		}
		if (validataNumber(Ai) == false) {
			errorInfo = "身份证15位号码都应为数字 ; 18位号码除最后一位外，都应为数字。";
			return errorInfo;
		}
		// =======================(end)========================

		// ================ 出生年月是否有效 ================
		String strYear = Ai.substring(6, 10);// 年份
		String strMonth = Ai.substring(10, 12);// 月份
		String strDay = Ai.substring(12, 14);// 月份
		if (dataFormat(strYear + "-" + strMonth + "-" + strDay) == false) {
			errorInfo = "身份证生日无效。";
			return errorInfo;
		}
		GregorianCalendar gc = new GregorianCalendar();
		SimpleDateFormat s = new SimpleDateFormat("yyyy-MM-dd");
		try {
			if ((gc.get(Calendar.YEAR) - Integer.parseInt(strYear)) > 150 || (gc.getTime().getTime() - s.parse(strYear + "-" + strMonth + "-" + strDay).getTime()) < 0) {
				errorInfo = "身份证生日不在有效范围。";
				return errorInfo;
			}
		} catch (Exception e) {
			errorInfo = "身份证生日不在有效范围。";
			return errorInfo;
		}
		if (Integer.parseInt(strMonth) > 12 || Integer.parseInt(strMonth) == 0) {
			errorInfo = "身份证月份无效";
			return errorInfo;
		}
		if (Integer.parseInt(strDay) > 31 || Integer.parseInt(strDay) == 0) {
			errorInfo = "身份证日期无效";
			return errorInfo;
		}
		// =====================(end)=====================

		// ================ 地区码时候有效 ================
		Map<String, String> h = GetAreaCode();
		if (h.get(Ai.substring(0, 2)) == null) {
			errorInfo = "身份证地区编码错误。";
			return errorInfo;
		}
		// ==============================================

		// ================ 判断最后一位的值 ================
		int TotalmulAiWi = 0;
		for (int i = 0; i < 17; i++) {
			TotalmulAiWi = TotalmulAiWi + Integer.parseInt(String.valueOf(Ai.charAt(i))) * Integer.parseInt(Wi[i]);
		}
		int modValue = TotalmulAiWi % 11;
		String strVerifyCode = ValCodeArr[modValue];
		Ai = Ai + strVerifyCode;

		if (IDStr.length() == 18) {
			if (Ai.equals(IDStr) == false) {
				errorInfo = "身份证无效，不是合法的身份证号码";
				return errorInfo;
			}
		} else {
			return null;
		}
		// =====================(end)=====================
		return null;
	}

	// /**
	// * 功能：判断字符串是否为数字
	// *
	// * @param str
	// * @return
	// */
	// private static boolean isNumeric(String str) {
	// return Pattern.compile("^[0-9]*$").matcher(str).matches();
	// }

	/**
	 * 功能：设置地区编码
	 * 
	 * @return Hashtable 对象
	 */
	private static Map<String, String> GetAreaCode() {
		Map<String, String> map = new HashMap<String, String>();
		map.put("11", "北京");
		map.put("12", "天津");
		map.put("13", "河北");
		map.put("14", "山西");
		map.put("15", "内蒙古");
		map.put("21", "辽宁");
		map.put("22", "吉林");
		map.put("23", "黑龙江");
		map.put("31", "上海");
		map.put("32", "江苏");
		map.put("33", "浙江");
		map.put("34", "安徽");
		map.put("35", "福建");
		map.put("36", "江西");
		map.put("37", "山东");
		map.put("41", "河南");
		map.put("42", "湖北");
		map.put("43", "湖南");
		map.put("44", "广东");
		map.put("45", "广西");
		map.put("46", "海南");
		map.put("50", "重庆");
		map.put("51", "四川");
		map.put("52", "贵州");
		map.put("53", "云南");
		map.put("54", "西藏");
		map.put("61", "陕西");
		map.put("62", "甘肃");
		map.put("63", "青海");
		map.put("64", "宁夏");
		map.put("65", "新疆");
		map.put("71", "台湾");
		map.put("81", "香港");
		map.put("82", "澳门");
		map.put("91", "国外");
		return map;
	}

	/**
	 * 验证日期字符串是否是YYYY-MM-DD格式
	 * 
	 * @param str
	 * @return
	 */
	public static boolean dataFormat(String str) {
		boolean flag = false;
		// String regxStr =
		// "[1-9][0-9]{3}-[0-1][0-2]-((0[1-9])|([12][0-9])|(3[01]))";
		String regxStr = "^((\\d{2}(([02468][048])|([13579][26]))[\\-\\/\\s]?((((0?[13578])|(1[02]))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])))))|(\\d{2}(([02468][1235679])|([13579][01345789]))[\\-\\/\\s]?((((0?[13578])|(1[02]))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\\-\\/\\s]?((0?[1-9])|(1[0-9])|(2[0-8]))))))(\\s(((0?[0-9])|([1-2][0-3]))\\:([0-5]?[0-9])((\\s)|(\\:([0-5]?[0-9])))))?$";
		Pattern pattern1 = Pattern.compile(regxStr);
		Matcher isNo = pattern1.matcher(str);
		if (isNo.matches()) {
			flag = true;
		}
		return flag;
	}

	/**
	 * 验证日期
	 * 
	 * @param str
	 *            模式为yyyy-MM-dd HH:mm:ss
	 * @return
	 */
	public static boolean isDataFormat(String str) {
		// boolean flag = false;
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		try {
			Date date = sdf.parse(str);
			str = sdf.format(date);
		} catch (Exception e) {
			// System.out.println(e.getMessage());
			return false;
		}
		return true;
	}

	/**
	 * 返回对象类型
	 */
	public static String classTypeFromObject(Object object) {
		return object.getClass().getSimpleName();
	}

	/**
	 * 转义html
	 * 
	 * @param paramStr
	 */
	public static String convertToHtml(String paramStr) {
		String str = paramStr.replace("\"", "&quot;");				// 双引号
		str = str.replace("'", "&apos;");							// 单引号
		str = str.replace("&", "&amp;");							// 和
		str = str.replace(">", "&gt;");								// 大于号
		str = str.replace("<", "&lt;");								// 小于号
		str = str.replace(" ", "&nbsp;");							// 空格
		return str;
	}

}
